package com.punch.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author tanchangguo
 * @date 2020/7/14 21:23
 */
public class MapUtil {

    private static final Object[] EMPTY_ARRAY = {};

    /**
     * 将一个bean转换成map
     *
     * @param map
     * @param bean
     * @return
     */
    public static Map<String, Object> populateMap(Map<String, Object> map, Object bean) {
        return populateMap(map, bean, null);
    }

    /**
     * 假设prefix=detail.，bean带有一个属性name，则map中将有一个项：
     * key=detail.name，value为bean的name属性值。
     */
    public static Map<String, Object> populateMap(Map<String, Object> map, Object bean, String prefix) {

        boolean withoutPrefix = StringUtils.isBlank(prefix);
        try {
            Method[] methods = bean.getClass().getMethods();
            for (Method method : methods) {

                String methodName = method.getName();
                Class[] pts = method.getParameterTypes();
                Class rt = method.getReturnType();

                if ((methodName.startsWith("get") || methodName.startsWith("is")) && pts.length == 0 && !Void.class.equals(rt)) {
                    String propName = null;
                    if (methodName.startsWith("get")) {
                        propName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
                    } else {
                        propName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3);
                    }
                    if ("class".equals(propName)) {
                        continue;
                    }

                    String key = withoutPrefix ? propName : prefix + propName;

                    Object value = method.invoke(bean, EMPTY_ARRAY);

                    if (value == null) {
                        continue;
                    }

                    if (value instanceof String) {
                        value = ((String) value).trim();
                    }
                    map.put(key, value);
                }
            }

            return map;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
